package logic

import (
	"context"
	"fmt"
	"strings"
	"time"

	"gb28181/gb28181"
	"gb28181/internal/protocol"
	"gb28181/internal/svc"

	"github.com/zeromicro/go-zero/core/logx"
)

type PTZControlLogic struct {
	ctx    context.Context
	svcCtx *svc.ServiceContext
	logx.Logger
}

func NewPTZControlLogic(ctx context.Context, svcCtx *svc.ServiceContext) *PTZControlLogic {
	return &PTZControlLogic{
		ctx:    ctx,
		svcCtx: svcCtx,
		Logger: logx.WithContext(ctx),
	}
}

func (l *PTZControlLogic) PTZControl(in *gb28181.PTZControlRequest) (*gb28181.PTZControlResponse, error) {
	// 检查设备是否存在
	device, exists := l.svcCtx.ClientMgr.GetDevice(in.DeviceId)
	if !exists {
		return &gb28181.PTZControlResponse{
			Success: false,
			Message: "设备不存在",
		}, nil
	}

	// 检查设备是否在线
	if !device.IsOnline() {
		return &gb28181.PTZControlResponse{
			Success: false,
			Message: "设备不在线",
		}, nil
	}

	// 验证PTZ命令
	if !l.isValidPTZCommand(in.Command) {
		return &gb28181.PTZControlResponse{
			Success: false,
			Message: "无效的PTZ命令",
		}, nil
	}

	// 验证速度参数
	if in.Speed < 0 || in.Speed > 100 {
		return &gb28181.PTZControlResponse{
			Success: false,
			Message: "速度参数必须在0-100之间",
		}, nil
	}

	// 执行PTZ控制
	err := l.executePTZCommand(in.DeviceId, in.ChannelId, in.Command, in.Speed)
	if err != nil {
		return &gb28181.PTZControlResponse{
			Success: false,
			Message: "PTZ控制执行失败: " + err.Error(),
		}, nil
	}

	return &gb28181.PTZControlResponse{
		Success: true,
		Message: "PTZ控制执行成功",
	}, nil
}

// 验证PTZ命令是否有效
func (l *PTZControlLogic) isValidPTZCommand(command string) bool {
	validCommands := []string{"left", "right", "up", "down", "zoom_in", "zoom_out", "focus_near", "focus_far", "iris_open", "iris_close", "stop"}
	for _, validCmd := range validCommands {
		if command == validCmd {
			return true
		}
	}
	return false
}

// 执行PTZ控制命令
func (l *PTZControlLogic) executePTZCommand(deviceId, channelId, command string, speed int32) error {
	// 根据GB28181协议发送PTZ控制指令
	l.Infof("执行PTZ控制: 设备=%s, 通道=%s, 命令=%s, 速度=%d", deviceId, channelId, command, speed)

	// 构建PTZ控制消息
	ptzCommand := l.mapPTZCommandToGB28181(command, speed)
	if ptzCommand == "" {
		return fmt.Errorf("不支持的PTZ命令: %s", command)
	}

	// 检查是否使用SIP格式
	useSIPFormat := l.shouldUseSIPFormat()

	if useSIPFormat {
		// 构建SIP格式的PTZ控制消息
		// 构建XML格式的PTZ控制消息体
		xmlBody := fmt.Sprintf(`<?xml version="1.0" encoding="UTF-8"?>
<Control>
  <CmdType>DeviceControl</CmdType>
  <SN>%d</SN>
  <DeviceID>%s</DeviceID>
  <PTZCmd>%s</PTZCmd>
  <Info>PTZ控制: %s</Info>
</Control>`, time.Now().Unix(), deviceId, ptzCommand, command)

		// 使用SIP MESSAGE方法发送PTZ控制消息
		err := l.svcCtx.MessageSender.SendSIPMessageToDevice(l.ctx, "MESSAGE", deviceId, xmlBody)
		if err != nil {
			return fmt.Errorf("发送SIP格式PTZ控制消息失败: %v", err)
		}
	} else {
		// 构建GB28181设备控制消息（XML格式）
		controlMessage, err := protocol.BuildDeviceControlMessage(
			deviceId,
			channelId,
			ptzCommand,
			fmt.Sprintf("PTZ控制: %s", command),
		)
		if err != nil {
			return fmt.Errorf("构建PTZ控制消息失败: %v", err)
		}

		// 发送PTZ控制消息到设备
		err = l.sendPTZControlMessage(deviceId, controlMessage)
		if err != nil {
			return fmt.Errorf("发送PTZ控制消息失败: %v", err)
		}
	}

	l.Infof("PTZ控制消息发送成功: 设备=%s, 通道=%s, 命令=%s", deviceId, channelId, command)
	return nil
}

// 将PTZ命令映射到GB28181协议命令
func (l *PTZControlLogic) mapPTZCommandToGB28181(command string, speed int32) string {
	// GB28181 PTZ控制命令格式: A2F + 命令代码(2位) + 速度(2位)
	// 速度需要格式化为2位数字
	speedStr := fmt.Sprintf("%02d", speed)

	switch strings.ToLower(command) {
	case "left":
		return fmt.Sprintf("A2F01%s", speedStr) // 左转
	case "right":
		return fmt.Sprintf("A2F02%s", speedStr) // 右转
	case "up":
		return fmt.Sprintf("A2F03%s", speedStr) // 上转
	case "down":
		return fmt.Sprintf("A2F04%s", speedStr) // 下转
	case "zoom_in":
		return fmt.Sprintf("A2F05%s", speedStr) // 变倍+
	case "zoom_out":
		return fmt.Sprintf("A2F06%s", speedStr) // 变倍-
	case "focus_near":
		return fmt.Sprintf("A2F07%s", speedStr) // 聚焦+
	case "focus_far":
		return fmt.Sprintf("A2F08%s", speedStr) // 聚焦-
	case "iris_open":
		return fmt.Sprintf("A2F09%s", speedStr) // 光圈+
	case "iris_close":
		return fmt.Sprintf("A2F0A%s", speedStr) // 光圈-
	case "stop":
		return "A2F0000" // 停止
	default:
		return ""
	}
}

// 发送PTZ控制消息到设备
func (l *PTZControlLogic) sendPTZControlMessage(deviceId string, message []byte) error {
	// 使用消息发送器发送PTZ控制消息
	err := l.svcCtx.MessageSender.SendMessageWithRetry(l.ctx, deviceId, message, 3)
	if err != nil {
		return fmt.Errorf("发送PTZ控制消息失败: %v", err)
	}

	l.Infof("PTZ控制消息发送成功: 设备=%s, 消息长度=%d", deviceId, len(message))
	return nil
}

// shouldUseSIPFormat 判断是否使用SIP格式
func (l *PTZControlLogic) shouldUseSIPFormat() bool {
	// 这里简化处理，实际应该从配置中读取
	// 暂时返回false，使用XML格式
	return false
}
